package cn.cutie.clotconfig.server;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @Description:
 * @Author: Cutie
 * @CreateDate: 2024/5/15 15:48
 * @Version: 0.0.1
 */
@Component
public class DistributedLocks {
//    @Autowired
//    LocksMapper locksMapper;

    @Autowired
    DataSource dataSource;

    Connection connection;

    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

    @Getter
    private AtomicBoolean locked = new AtomicBoolean(false);

    @PostConstruct
    public void init() {
        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        executor.scheduleWithFixedDelay(this::tryLock, 1000, 5000, TimeUnit.MILLISECONDS);
    }

    public boolean lock() throws SQLException {
//        String s = locksMapper.selectForUpdate();
        connection.setAutoCommit(false);
        connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
        connection.createStatement().execute("set innodb_lock_wait_timeout=5"); // 只对这个连接有效
        connection.createStatement().execute("select app from locks where id = 1 for update"); // 数据库锁5秒钟
        if (locked.get()){
            System.out.println("===>>> reenter this dist lock");
        } else {
            System.out.println("===>>> get a dist lock");
        }
        return true;
    }

    public void tryLock() {
        try {
            lock();
            locked.set(true);
        } catch (Exception e){
            System.out.println("===>>> locker failed");
            locked.set(false);
        }
    }

    @PreDestroy
    public void close(){
        try {
            if (connection != null && !connection.isClosed()){
                connection.rollback();
                connection.close();
            }
        } catch (SQLException e){
            System.out.println("ignore this close exception");
        }
    }

}
